Skip to content

Add jumbo frame support & fix Stream2UDPTX freeze-up#197

Merged
enjoy-digital merged 2 commits intoenjoy-digital:masterfrom
meriac:master
Mar 30, 2026
Merged

Add jumbo frame support & fix Stream2UDPTX freeze-up#197
enjoy-digital merged 2 commits intoenjoy-digital:masterfrom
meriac:master

Conversation

@meriac
Copy link
Copy Markdown
Contributor

@meriac meriac commented Mar 26, 2026

Why jumbo frames matter

Standard Ethernet frames are limited to a 1500-byte payload (1530 bytes including headers). For high-throughput streaming applications — such as SDR IQ sample transport — this means the CPU must process one interrupt and one DMA transaction per 1500 bytes of data. At 30.72 MSPS × 4 bytes/sample × 2 channels = 245 MB/s, that's over 160,000 packets per second, creating significant CPU overhead from interrupt handling, context switches, and per-packet protocol processing.

Jumbo frames (up to ~9000-byte payload) reduce this by ~6×: fewer packets, fewer interrupts, fewer DMA setup cycles, and better cache utilization. This directly translates to lower CPU usage and more headroom for real-time signal processing.

What changed

Previously, eth_mtu was a hardcoded global constant (1530) in liteeth/common.py, imported via from liteeth.common import * by all MAC/IP/UDP modules. There was no way to override it without patching the global at runtime — a fragile approach dependent on Python import ordering.

This commit makes eth_mtu a proper constructor parameter threaded through the entire class hierarchy, with the original value as the default for full backward compatibility.

Constants (liteeth/common.py)

  • Renamed eth_mtueth_mtu_default (1530) to clarify it's a default, not a fixed value - and prevent accidental usage instead of the new parameter-passing approach
  • Added eth_mtu_jumboframe (9022) as a standard jumbo frame constant
  • Removed unused buffer_depth derived constant (would be dangerous to keep - must be calculated from the actual MTU size instead)

Parameter threading (6 source files)

Added eth_mtu=eth_mtu_default parameter to the following classes, each passing it down to its children:

  • LiteEthUDPIPCore / LiteEthIPCore (core/__init__.py) → passes to LiteEthMAC
  • LiteEthMAC (mac/__init__.py) → passes to LiteEthMACCore and LiteEthMACWishboneInterface
  • LiteEthMACCore (mac/core.py) → passes to LiteEthMACPaddingChecker
  • LiteEthMACPaddingChecker (mac/padding.py) → uses eth_mtu for length counter signal width
  • LiteEthMACWishboneInterface (mac/wishbone.py) → uses eth_mtu for SRAM depth calculation and Wishbone address decoding; passes to LiteEthMACSRAM
  • LiteEthMACSRAM / LiteEthMACSRAMWriter (mac/sram.py) → uses eth_mtu for the packet truncation threshold (If(length >= self.eth_mtu, DISCARD-REMAINING))

Tests (6 test files)

All test files now run at both eth_mtu_default (1530) and eth_mtu_jumboframe (9022) using unittest.subTest:

  • test_arp.py, test_icmp.py, test_ip.py, test_udp.py, test_etherbone.py — DUT accepts eth_mtu parameter, test loops over both MTU values
  • test_mac_wishbone.py — additionally replaces hardcoded SRAM slot offsets (0x200) with dynamically computed values based on eth_mtu and dw, since the Wishbone address decoder requires power-of-2 aligned slot boundaries that scale with MTU

meriac added 2 commits March 26, 2026 15:43
When the enable signal is deasserted while a UDP packet is mid-flight
(source.valid still high, FSM in SEND state), the ResetInserter
immediately resets the FSM back to IDLE. This drops source.valid without
ever asserting source.last, violating the AXI-Stream protocol contract.
Downstream consumers (e.g. LiteEth UDP/IP stack) that rely on last to
delimit packets will either hang waiting for the end-of-packet or
concatenate the truncated data with the next packet.

The fix gates the FSM reset on ~source.valid so that a disable request
is deferred until the current packet finishes its last beat. Once the
FSM returns to IDLE and source.valid goes low, the reset takes effect
normally.

    old: fsm.reset.eq(~self.enable)
    new: fsm.reset.eq(~self.enable & ~source.valid)

Add tests that disable the module at the first word, midpoint, and final
word of a packet, verifying that the packet always completes with last
asserted and that the module recovers for subsequent packets.
@meriac meriac changed the title Add configurable eth_mtu parameter for jumbo frame support Add jumbo frame support & fix Stream2UDPTX freeze-up Mar 30, 2026
@enjoy-digital
Copy link
Copy Markdown
Owner

Thanks @meriac! This looks good.

@enjoy-digital enjoy-digital merged commit e82cba3 into enjoy-digital:master Mar 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants